package com.sqlcheck.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqlcheck.common.enums.DatabaseType;
import com.sqlcheck.dto.request.CreateCompatibilityRuleRequest;
import com.sqlcheck.dto.request.UpdateCompatibilityRuleRequest;
import com.sqlcheck.dto.response.CompatibilityRuleResponse;
import com.sqlcheck.entity.CompatibilityRule;
import com.sqlcheck.repository.CompatibilityRuleRepository;
import com.sqlcheck.service.CompatibilityRuleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class CompatibilityRuleServiceImpl implements CompatibilityRuleService {

    private final CompatibilityRuleRepository ruleRepository;

    @Override
    public IPage<CompatibilityRuleResponse> getRules(Page<CompatibilityRuleResponse> page,
            String sourceDbType, String targetDbType, String severity, String category, String search) {

        // 创建分页对象，使用CompatibilityRule实体
        Page<CompatibilityRule> entityPage = new Page<>(page.getCurrent(), page.getSize());

        LambdaQueryWrapper<CompatibilityRule> wrapper = new LambdaQueryWrapper<>();

        // 添加筛选条件
        if (StringUtils.hasText(sourceDbType)) {
            try {
                CompatibilityRule.DbType srcType = CompatibilityRule.DbType.valueOf(sourceDbType);
                wrapper.eq(CompatibilityRule::getSourceDbType, srcType);
            } catch (IllegalArgumentException e) {
                log.warn("无效的源数据库类型: {}", sourceDbType);
            }
        }

        if (StringUtils.hasText(targetDbType)) {
            try {
                CompatibilityRule.DbType tgtType = CompatibilityRule.DbType.valueOf(targetDbType);
                wrapper.eq(CompatibilityRule::getTargetDbType, tgtType);
            } catch (IllegalArgumentException e) {
                log.warn("无效的目标数据库类型: {}", targetDbType);
            }
        }

        if (StringUtils.hasText(severity)) {
            try {
                CompatibilityRule.Severity sev = CompatibilityRule.Severity.valueOf(severity);
                wrapper.eq(CompatibilityRule::getSeverity, sev);
            } catch (IllegalArgumentException e) {
                log.warn("无效的严重程度: {}", severity);
            }
        }

        if (StringUtils.hasText(category)) {
            wrapper.eq(CompatibilityRule::getCategory, category);
        }

        if (StringUtils.hasText(search)) {
            wrapper.and(w -> w.like(CompatibilityRule::getRuleName, search)
                    .or().like(CompatibilityRule::getRuleId, search));
        }

        // 排序：按创建时间倒序
        wrapper.orderByDesc(CompatibilityRule::getCreatedAt);

        // 执行查询
        IPage<CompatibilityRule> rulePage = ruleRepository.selectPage(entityPage, wrapper);

        // 转换为响应对象
        List<CompatibilityRuleResponse> responses = rulePage.getRecords().stream()
                .map(CompatibilityRuleResponse::fromEntity)
                .collect(Collectors.toList());

        // 创建新的分页对象
        Page<CompatibilityRuleResponse> responsePage = new Page<>(page.getCurrent(), page.getSize());
        responsePage.setRecords(responses);
        responsePage.setTotal(rulePage.getTotal());
        responsePage.setCurrent(rulePage.getCurrent());
        responsePage.setSize(rulePage.getSize());

        log.info("查询兼容性规则: 筛选条件={}, 结果数量={}",
                String.format("sourceDbType=%s, targetDbType=%s, severity=%s, category=%s, search=%s",
                        sourceDbType, targetDbType, severity, category, search),
                responses.size());

        return responsePage;
    }

    @Override
    public CompatibilityRuleResponse getRuleById(Long ruleId) {
        log.info("根据ID获取规则详情: ruleId={}", ruleId);

        CompatibilityRule rule = ruleRepository.selectById(ruleId);
        if (rule == null) {
            throw new RuntimeException("规则不存在: " + ruleId);
        }

        return CompatibilityRuleResponse.fromEntity(rule);
    }

    @Override
    public CompatibilityRuleResponse getRuleByRuleId(String ruleId) {
        log.info("根据规则编号获取规则详情: ruleId={}", ruleId);

        LambdaQueryWrapper<CompatibilityRule> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CompatibilityRule::getRuleId, ruleId)
                .eq(CompatibilityRule::getIsActive, true); // 只返回启用的规则

        CompatibilityRule rule = ruleRepository.selectOne(wrapper);
        if (rule == null) {
            throw new RuntimeException("规则不存在或未启用: " + ruleId);
        }

        return CompatibilityRuleResponse.fromEntity(rule);
    }

    @Override
    public List<CompatibilityRule> getRulesForLLMOptimization(DatabaseType sourceDbType, DatabaseType targetDbType) {
        log.info("获取LLM优化兼容性规则: {} -> {}", sourceDbType, targetDbType);

        LambdaQueryWrapper<CompatibilityRule> wrapper = new LambdaQueryWrapper<>();

        // 映射DatabaseType到CompatibilityRule.DbType
        CompatibilityRule.DbType sourceDb = mapDatabaseType(sourceDbType);
        CompatibilityRule.DbType targetDb = mapDatabaseType(targetDbType);

        if (sourceDb != null) {
            wrapper.eq(CompatibilityRule::getSourceDbType, sourceDb);
        }
        if (targetDb != null) {
            wrapper.eq(CompatibilityRule::getTargetDbType, targetDb);
        }

        // 只获取启用的规则
        wrapper.eq(CompatibilityRule::getIsActive, true);

        // 按严重程度和优先级排序：CRITICAL > HIGH > MEDIUM > LOW
        wrapper.orderByAsc(CompatibilityRule::getSeverity)
                .orderByDesc(CompatibilityRule::getCreatedAt);

        // 限制数量，避免提示词过长
        wrapper.last("LIMIT 20");

        List<CompatibilityRule> rules = ruleRepository.selectList(wrapper);

        log.info("找到 {} 条适用的兼容性规则", rules.size());

        return rules;
    }

    @Override
    @Transactional
    public CompatibilityRuleResponse createRule(CreateCompatibilityRuleRequest request) {
        log.info("创建兼容性规则: ruleId={}, ruleName={}", request.getRuleId(), request.getRuleName());

        // 检查规则ID是否已存在
        LambdaQueryWrapper<CompatibilityRule> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CompatibilityRule::getRuleId, request.getRuleId());
        if (ruleRepository.selectCount(wrapper) > 0) {
            throw new RuntimeException("规则ID已存在: " + request.getRuleId());
        }

        // 创建新规则
        CompatibilityRule rule = new CompatibilityRule();
        BeanUtils.copyProperties(request, rule);

        // 设置默认值
        if (rule.getIsActive() == null) {
            rule.setIsActive(true);
        }

        int result = ruleRepository.insert(rule);
        if (result <= 0) {
            throw new RuntimeException("创建规则失败");
        }

        log.info("兼容性规则创建成功: id={}, ruleId={}", rule.getId(), rule.getRuleId());
        return CompatibilityRuleResponse.fromEntity(rule);
    }

    @Override
    @Transactional
    public CompatibilityRuleResponse updateRule(Long ruleId, UpdateCompatibilityRuleRequest request) {
        log.info("更新兼容性规则: ruleId={}, ruleName={}", ruleId, request.getRuleName());

        // 检查规则是否存在
        CompatibilityRule existingRule = ruleRepository.selectById(ruleId);
        if (existingRule == null) {
            throw new RuntimeException("规则不存在: " + ruleId);
        }

        // 更新规则
        CompatibilityRule rule = new CompatibilityRule();
        BeanUtils.copyProperties(request, rule);
        rule.setId(ruleId);

        int result = ruleRepository.updateById(rule);
        if (result <= 0) {
            throw new RuntimeException("更新规则失败");
        }

        // 返回更新后的规则
        CompatibilityRule updatedRule = ruleRepository.selectById(ruleId);
        log.info("兼容性规则更新成功: ruleId={}", ruleId);
        return CompatibilityRuleResponse.fromEntity(updatedRule);
    }

    @Override
    @Transactional
    public CompatibilityRuleResponse toggleRuleStatus(Long ruleId) {
        log.info("切换规则状态: ruleId={}", ruleId);

        // 获取当前规则
        CompatibilityRule rule = ruleRepository.selectById(ruleId);
        if (rule == null) {
            throw new RuntimeException("规则不存在: " + ruleId);
        }

        // 切换状态
        Boolean newStatus = !rule.getIsActive();

        LambdaUpdateWrapper<CompatibilityRule> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(CompatibilityRule::getId, ruleId)
                .set(CompatibilityRule::getIsActive, newStatus);

        int result = ruleRepository.update(null, updateWrapper);
        if (result <= 0) {
            throw new RuntimeException("切换规则状态失败");
        }

        // 返回更新后的规则
        CompatibilityRule updatedRule = ruleRepository.selectById(ruleId);
        log.info("规则状态切换成功: ruleId={}, newStatus={}", ruleId, newStatus);
        return CompatibilityRuleResponse.fromEntity(updatedRule);
    }

    @Override
    @Transactional
    public void deleteRule(Long ruleId) {
        log.info("删除兼容性规则: ruleId={}", ruleId);

        // 检查规则是否存在
        CompatibilityRule rule = ruleRepository.selectById(ruleId);
        if (rule == null) {
            throw new RuntimeException("规则不存在: " + ruleId);
        }

        // 执行软删除
        int result = ruleRepository.deleteById(ruleId);
        if (result <= 0) {
            throw new RuntimeException("删除规则失败");
        }

        log.info("兼容性规则删除成功: ruleId={}", ruleId);
    }

    @Override
    @Transactional
    public void batchUpdateRuleStatus(List<Long> ruleIds, Boolean isActive) {
        log.info("批量更新规则状态: ruleIds={}, isActive={}", ruleIds, isActive);

        if (ruleIds == null || ruleIds.isEmpty()) {
            throw new RuntimeException("规则ID列表不能为空");
        }

        LambdaUpdateWrapper<CompatibilityRule> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(CompatibilityRule::getId, ruleIds)
                .set(CompatibilityRule::getIsActive, isActive);

        int result = ruleRepository.update(null, updateWrapper);
        log.info("批量更新规则状态完成: 影响行数={}", result);
    }

    /**
     * 映射DatabaseType到CompatibilityRule.DbType
     */
    private CompatibilityRule.DbType mapDatabaseType(DatabaseType databaseType) {
        if (databaseType == null)
            return null;

        try {
            switch (databaseType) {
                case MYSQL:
                    return CompatibilityRule.DbType.MYSQL;
                case ORACLE:
                    return CompatibilityRule.DbType.ORACLE;
                case GOLDENDB:
                    return CompatibilityRule.DbType.GOLDENDB;
                default:
                    log.warn("未知的数据库类型: {}", databaseType);
                    return null;
            }
        } catch (Exception e) {
            log.warn("映射数据库类型失败: {}", databaseType, e);
            return null;
        }
    }
}
